package com.itheima.stock.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.stock.entity.*;
import com.itheima.stock.mapper.*;
import com.itheima.stock.properties.MarketProperties;
import com.itheima.stock.response.PageResult;
import com.itheima.stock.service.StockService;
import com.itheima.stock.util.DateTimeUtil;
import com.itheima.stock.vo.*;

import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author zby
 * @created 2024-06-23 16:34
 * @description 股票业务实现类
 */
@Service
public class StockServiceImpl implements StockService {

    private final StockRtInfoMapper stockRtInfoMapper;
    private final StockBlockRtInfoMapper stockBlockRtInfoMapper;
    private final StockMarketLogPriceMapper marketMarketLogPriceMapper;
    private final MarketProperties marketProperties;
    private final StockBusinessMapper stockBusinessMapper;
    private final StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    public StockServiceImpl(StockBusinessMapper stockBusinessMapper, MarketProperties marketProperties, StockMarketIndexInfoMapper marketMarketIndexInfoMapper, StockMarketLogPriceMapper marketMarketLogPriceMapper, StockMarketIndexInfoMapper stockMarketIndexInfoMapper, StockBlockRtInfoMapper stockBlockRtInfoMapper, StockRtInfoMapper stockRtInfoMapper) {
        this.stockBusinessMapper = stockBusinessMapper;
        this.marketProperties = marketProperties;
        this.marketMarketLogPriceMapper = marketMarketLogPriceMapper;
        this.stockMarketIndexInfoMapper = stockMarketIndexInfoMapper;
        this.stockBlockRtInfoMapper = stockBlockRtInfoMapper;
        this.stockRtInfoMapper = stockRtInfoMapper;
    }


    @Override
    public UpDownVO<CountVo> UpDown() {
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //TODO mockDate 模拟时间
        LocalDateTime start = LocalDateTime.parse("20220106092500", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        LocalDateTime end = LocalDateTime.parse("20220106142500", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        List<CountVo> upList = stockRtInfoMapper.UpDown(start, end,true);
        List<CountVo> downList = stockRtInfoMapper.UpDown(start, end,false);
        return UpDownVO.<CountVo>builder()
                .upList(upList)
                .downList(downList)
                .build();
    }

    @Override
    public PageResult<MoreVO> more(Integer page, Integer pageSize) {
        //距离当前时间最近的交易时间
        //LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //mockDate 模拟时间
               final LocalDateTime last = LocalDateTime.parse("20211230093200", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        Page<MoreVO> stockRtInfos = PageHelper.startPage(page, pageSize).doSelectPage(() -> {
            List<MoreVO> list = stockRtInfoMapper.selectMore(last);
        });

        return PageResult.<MoreVO>builder()
                .totalRows(stockRtInfos.getTotal())
                .size(stockRtInfos.getPageSize())
                .totalPages(stockRtInfos.getPages())
                .pageSize(stockRtInfos.getPageSize())
                .pageNum(stockRtInfos.getPageNum())
                .rows(stockRtInfos.getResult())
                .build();
    }

    /**
     * 股票主营业务信息
     *
     * @return
     */
    @Override
    public List<StockBusiness> getStockBusiness() {
        return stockBusinessMapper.selectAll();
    }

    /**
     * 内盘信息
     *
     * @return
     */
    @Override
    public List<MarketIndexVO> innerIndexAll() {

        List<String> ids = marketProperties.getInner();
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        String mockDate = "20211226105600";
        last = LocalDateTime.parse(mockDate, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        List<StockMarketIndexInfo> list = stockMarketIndexInfoMapper.selectByIdsAndDateTime(ids, last);
        List<StockMarketLogPrice> list1 = marketMarketLogPriceMapper.selectByIdsAndDateTime(ids, last.toLocalDate());
        return list.stream().map((marketIndexInfo) -> {
            MarketIndexVO VO = MarketIndexVO.builder()
                    .code(marketIndexInfo.getMarkId())
                    .curDate(marketIndexInfo.getCurTime().toLocalDate().toString())
                    .name(marketIndexInfo.getMarkName())
                    .tradeAmt(marketIndexInfo.getTradeAccount())
                    .tradeVol(marketIndexInfo.getTradeVolume())
                    .upDown(marketIndexInfo.getUpdownRate())
                    .tradePrice(marketIndexInfo.getCurrentPrice())
                    .build();
            list1.forEach((marketLogPrice) -> {

                if (marketLogPrice.getMarketCode().equals(marketIndexInfo.getMarkId())) {
                    VO.setPreClosePrice(marketLogPrice.getPreClosePrice());
                    VO.setOpenPrice(marketLogPrice.getOpenPrice());
                } else if ((VO.getPreClosePrice() == null || VO.getPreClosePrice().equals(BigDecimal.ZERO))
                        && (VO.getOpenPrice() == null || VO.getOpenPrice().equals(BigDecimal.ZERO))) {
                    VO.setOpenPrice(BigDecimal.ZERO);
                    VO.setPreClosePrice(BigDecimal.ZERO);
                }
            });
            return VO;
        }).toList();
    }

    /**
     * 板块信息
     *
     * @return
     */
    @Override
    public List<SectorAllVO> SectorAll() {
        LocalDateTime last = LocalDateTime.parse("20211221000000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        LocalDateTime start = DateTimeUtil.getOpenDate(last);
        LocalDateTime end = DateTimeUtil.getCloseDate(last);
        List<StockBlockRtInfo> list = stockBlockRtInfoMapper.selectByDateTimeDesc(start, end);
        return list.stream().map(stockBlockRtInfo -> SectorAllVO.builder()
                .avgPrice(stockBlockRtInfo.getAvgPrice())
                .code(stockBlockRtInfo.getLabel())
                .companyNum(stockBlockRtInfo.getCompanyNum())
                .curDate(stockBlockRtInfo.getCurTime().toLocalDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")))
                .name(stockBlockRtInfo.getBlockName())
                .tradeAmt(stockBlockRtInfo.getTradeAmount())
                .tradeVol(stockBlockRtInfo.getTradeVolume())
                .updownRate(stockBlockRtInfo.getUpdownRate())
                .build()).toList();
    }

    /**
     * 股票涨幅榜
     *
     * @return
     */
    @Override
    public List<IncreaseVO> increase() {
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //模拟日期
        last = LocalDateTime.parse("2021-12-30 09:32:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<StockRtInfo> list = stockRtInfoMapper.selectByDateTime(last);
        List<IncreaseVO> result = new ArrayList<>();
        list.stream().forEach(stockRtInfo -> {
            IncreaseVO vo = new IncreaseVO();
            vo.setCode(stockRtInfo.getStockCode());
            vo.setName(stockRtInfo.getStockName());
            vo.setTradePrice(stockRtInfo.getCurPrice());
            vo.setTradeAmt(stockRtInfo.getTradeAmount());
            vo.setTradeVol(stockRtInfo.getTradeVolume());
            vo.setPreClosePrice(stockRtInfo.getPreClosePrice());
            vo.setCurDate(stockRtInfo.getCurTime().toLocalDate().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            BigDecimal upDown = stockRtInfo.getCurPrice().subtract(stockRtInfo.getPreClosePrice());
            // 涨跌
            vo.setUpDown(upDown);
            // 涨幅
            vo.setIncrease(upDown.divide(stockRtInfo.getPreClosePrice(), 6, RoundingMode.HALF_UP).multiply(new BigDecimal("1.0")));
            // 振幅
            vo.setAmplitude((stockRtInfo.getMaxPrice().subtract(stockRtInfo.getMinPrice())).divide(stockRtInfo.getPreClosePrice(), 6, RoundingMode.HALF_UP).multiply(new BigDecimal("1.0")));
            result.add(vo);
        });
        List<IncreaseVO> resultList = result.stream().sorted((o1, o2) -> o2.getUpDown().compareTo(o1.getUpDown())).limit(10).toList();
        return resultList;
    }

    @Override
    public TradeAmtVO<CountVo> tradeAmt() {
        LocalDateTime t = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        LocalDateTime t_1 = DateTimeUtil.getPreviousTradingDay(t);


        LocalDateTime t_open = LocalDateTime.parse("20211228093000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        LocalDateTime t_close = LocalDateTime.parse("20211228143000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

        LocalDateTime t_1_open = LocalDateTime.parse("20211227093000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        LocalDateTime t_1_close = LocalDateTime.parse("20211227143000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        List<String> ids = marketProperties.getInner();
        List<CountVo> list = stockMarketIndexInfoMapper.tradeAmt(t_1_open,t_close,ids);
        LocalDate tDate = t_open.toLocalDate();
        LocalDate t_1Date = t_1_open.toLocalDate();

        List<CountVo> tList = list.stream().filter((vo) -> {
            LocalDateTime parse = LocalDateTime.parse(vo.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDate targetDate = parse.toLocalDate();
            return targetDate.isEqual(tDate);
        }).toList();

        List<CountVo> t_1List = list.stream().filter((vo) -> {
            LocalDateTime parse = LocalDateTime.parse(vo.getTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            LocalDate targetDate = parse.toLocalDate();
            return targetDate.isEqual(t_1Date);
        }).toList();
        return TradeAmtVO.<CountVo>builder()
                .volList(tList)
                .yesVolList(t_1List)
                .build();
    }

    @Override
    public StockUpDownVO stockUpDown() {

        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());

        //MOCK data
        last = LocalDateTime.parse("2022-01-06 09:55:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        List<StockUpDownVO.Info> infos = stockRtInfoMapper.selectStockUpDown(last);

        return StockUpDownVO.builder()
                .time(last)
                .infos(infos)
                .build();

    }
}
